﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace Pcb.Common
{
    /// <summary>
    /// DES加密解密
    /// </summary>
    public class _DESEncrypt
    {
        private static string Iv = "12345678";
        private static string Key = "12345678";
        private static Encoding Encod = new UnicodeEncoding();
        private static DES Des = new DESCryptoServiceProvider();

        public _DESEncrypt()
        {           
        }

        /// <summary>
        /// 加密字符串并返回加密后的结果
        /// </summary>        
        public static string EncryptString(string Str)
        {
            byte[] Ivb = Encoding.ASCII.GetBytes(Iv);
            byte[] Keyb = Encoding.ASCII.GetBytes(Key);                 //得到默认加密密钥
            byte[] ToEncrypt = Encod.GetBytes(Str);         //得到要加密的内容
            byte[] Encrypted;

            ICryptoTransform Encryptor = Des.CreateEncryptor(Keyb, Ivb);
            MemoryStream MsEncrypt = new MemoryStream();
            CryptoStream CsEncrypt = new CryptoStream(MsEncrypt, Encryptor, CryptoStreamMode.Write);
            CsEncrypt.Write(ToEncrypt, 0, ToEncrypt.Length);
            CsEncrypt.FlushFinalBlock();
            Encrypted = MsEncrypt.ToArray();
            CsEncrypt.Close();
            MsEncrypt.Close();

            return Encod.GetString(Encrypted);
        }

        /// <summary>
        /// 加密指定的文件,如果成功返回True,否则false
        /// </summary>
        /// <param name="FilePath">要加密的文件路径</param>
        /// <param name="OutPath">加密后的文件输出路径</param>
        public static bool EncryptFile(string FilePath, string OutPath)
        {
            bool IsExist = File.Exists(FilePath);

            if (IsExist)
            {
                byte[] Ivb = Encoding.ASCII.GetBytes(Iv);
                byte[] Keyb = Encoding.ASCII.GetBytes(Key);         //得到要加密文件的字节流
                FileStream Fin = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                StreamReader Reader = new StreamReader(Fin, Encod);
                string DataStr = Reader.ReadToEnd();
                byte[] ToEncrypt = Encod.GetBytes(DataStr);
                Fin.Close();
                FileStream Fout = new FileStream(OutPath, FileMode.Create, FileAccess.Write);
                ICryptoTransform Encryptor = Des.CreateEncryptor(Keyb, Ivb);
                CryptoStream CsEncrypt = new CryptoStream(Fout, Encryptor, CryptoStreamMode.Write);

                try
                {
                    //加密得到的文件字节流
                    CsEncrypt.Write(ToEncrypt, 0, ToEncrypt.Length);
                    CsEncrypt.FlushFinalBlock();
                }
                catch (Exception Err)
                {
                    throw new ApplicationException(Err.Message);
                }
                finally
                {
                    try
                    {
                        Fout.Close();
                        CsEncrypt.Close();
                    }
                    catch
                    {                        
                    }
                }
            }
            else
            {
                throw new FileNotFoundException("没有找到指定的文件");
            }

            return IsExist;
        }

        /// <summary>
        /// 文件加密函数,如果不指定输出路径,那么原来的文件将被加密后的文件覆盖
        /// </summary>        
        public static bool EncryptFile(string FilePath)
        {
            return EncryptFile(FilePath, FilePath);
        }

        /// <summary>
        /// 解密字符串,返回解密后的字符串
        /// </summary>
        /// <param name="Str">需要解密的字符串</param>
        public static string DecryptString(string Str)
        {
            byte[] Ivb = Encoding.ASCII.GetBytes(Iv);
            byte[] Keyb = Encoding.ASCII.GetBytes(Key);
            byte[] ToDecrypt = Encod.GetBytes(Str);
            byte[] DeCrypted = new byte[ToDecrypt.Length];
            ICryptoTransform DeCryptor = Des.CreateDecryptor(Keyb, Ivb);
            MemoryStream MsDecrypt = new MemoryStream(ToDecrypt);
            CryptoStream CsDecrypt = new CryptoStream(MsDecrypt, DeCryptor, CryptoStreamMode.Read);
            try
            {
                CsDecrypt.Read(DeCrypted, 0, DeCrypted.Length);
            }
            catch (Exception Err)
            {
                throw new ApplicationException(Err.Message);
            }
            finally
            {
                try
                {
                    MsDecrypt.Close();
                    CsDecrypt.Close();
                }
                catch 
                { 
                }
            }

            return Encod.GetString(DeCrypted);
        }
        
        /// <summary>
        /// 解密指定的文件,如果成功返回True,否则false
        /// </summary>
        /// <param name="FilePath">要解密的文件路径</param>
        /// <param name="OutPath">解密后的文件输出路径</param>
        public static bool DecryptFile(string FilePath, string OutPath)
        {
            bool IsExist = File.Exists(FilePath);

            if (IsExist)//如果存在
            {
                byte[] Ivb = Encoding.ASCII.GetBytes(Iv);
                byte[] Keyb = Encoding.ASCII.GetBytes(Key);
                FileInfo Files = new FileInfo(FilePath);
                byte[] DeCrypted = new byte[Files.Length];
                //得到要解密文件的字节流
                FileStream Fin = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
                //解密文件
                try
                {
                    ICryptoTransform Decryptor = Des.CreateDecryptor(Keyb, Ivb);
                    CryptoStream CsDecrypt = new CryptoStream(Fin, Decryptor, CryptoStreamMode.Read);
                    CsDecrypt.Read(DeCrypted, 0, DeCrypted.Length);
                }
                catch (Exception Err)
                {
                    throw new ApplicationException(Err.Message);
                }
                finally
                {
                    try
                    {
                        Fin.Close();
                    }
                    catch { ;}
                }
                FileStream Fout = new FileStream(OutPath, FileMode.Create, FileAccess.Write);
                Fout.Write(DeCrypted, 0, DeCrypted.Length);
                Fout.Close();
            }
            else
            {
                throw new FileNotFoundException("指定的解密文件没有找到");
            }

            return IsExist;
        }
        
        /// <summary>
        /// 解密文件,如果没有给出解密后文件的输出路径,则解密后的文件将覆盖先前的文件
        /// </summary>
        /// <param name="FilePath"></param>
        public static bool DecryptFile(string FilePath)
        {
            return DecryptFile(FilePath, FilePath);
        }

    }
}
